﻿using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XTYAPI.PLC
{
    /// <summary>
    /// 加计数器
    /// WangdDong QQ851879790
    /// 可以使用“加计数”指令递增 CV 参数的值。如果参数 CU 的信号状态从“0”变为“1”（信号上升沿），则执行该指令，同时参数 CV 的当前计数器值加“1”。
    /// 每检测到一个上升沿，计数器值就会递增，直到其达到参数 CV 中所指定数据类型的上限。
    /// 达到上限时，参数 CU 的信号状态将不再影响该指令。
    /// 可以通过参数 Q 查询计数状态。参数 Q 的信号状态由参数 PV 决定。
    /// 如果当前计数器值大于或等于参数 PV 的值，则参数 Q 的信号状态将置位为“1”。
    /// 在其它任何情况下，参数 Q 的信号状态均为“0”。也可以为参数 PV 指定一个常数。
    /// 参数 R 的信号状态变为“1”时，参数 CV 的值将复位为“0”。只要参数 R 的信号状态为“1”，参数 CU 的信号状态就不会影响该指令。
    /// </summary>
    public class CTU
    {
        public CTU()
        {
        }
        public CTU( int pv) : this()
        {
            this.PV = pv;        
        }
        bool cu, r;
        int pv;
        /// <summary>
        /// 溢出
        /// </summary>
        public bool Spill { get; set; } = true;
        /// <summary>
        /// 加数输入
        /// </summary>
        public  bool  CU
        {
            get
            {          
                return cu;
            }
            set
            {
                if (R)
                {
                    return;
                }
                if (value && !cu)
                {
                    if (CV< PV)
                    {
                        CV++;
                    }
                    else
                    {
                        if (Spill)
                        {
                            CV++;
                        }
                        else
                        {
                            CV = PV;
                        }
                    }                                     
                }
                Q = CV >= PV;
                cu =  value;
            }
        }
        /// <summary>
        /// 复位输入
        /// </summary>
        public bool R
        {
            get { return r; } 
            set
            {
                if (value)
                {
                    CV = 0;
                }
                r = value;
            } 
        }
        /// <summary>
        /// 置位输出 Q 的目标值
        /// </summary>
        public  int PV
        {
            get { return pv; }
            set
            {
                if (pv != value)
                {
                    pv = value;
                }
                pv = value;
            }
        }
        /// <summary>
        /// 计数器状态
        /// </summary>
        public bool Q { get { return Q = CV >= PV; } private set { } }
        /// <summary>
        /// 当前计数器值
        /// </summary>
        public  int CV { get; private set; }
    }
}
